package com.youkeda.comment.service.impl;


import com.youkeda.comment.dao.CommentDAO;
import com.youkeda.comment.dataobject.CommentDO;
import com.youkeda.comment.model.Comment;
import com.youkeda.comment.model.Result;
import com.youkeda.comment.model.User;
import com.youkeda.comment.service.CommentService;
import com.youkeda.comment.service.UserService;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @ClassName CommentServiceImpl
 * @Author 刘正星
 * @Date 2020/7/18 16:24
 **/
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentDAO commentDAO;
    @DubboReference(version = "${user.service.version}")
    private UserService userService;

    @Override
    public List<Comment> findAll() {
        List<CommentDO> commentDOS = commentDAO.findAll();
        if (CollectionUtils.isEmpty(commentDOS)) {
            return null;
        }
        List<Long> userIds = commentDOS.stream().map(CommentDO::getUserId).collect(Collectors.toList());
        //获取User实例
        List<User> users = userService.findByIds(userIds);
        Map<Long,User> userMap = new HashMap<>();
        for (User user:users){
            userMap.put(user.getId(),user);
        }
        List<Comment> comments = new ArrayList<>();
      for (CommentDO commentDO: commentDOS){
          Comment comment = commentDO.toModel();
          User author = userMap.get(comment.getAuthor().getId());
          if (author!=null){
              comment.setAuthor(author);
          }
          comments.add(comment);
      }
        return comments;
    }

    @Override
    public int add(Comment comment) {
        if (comment == null) {
            return 0;
        }
        CommentDO commentDO = new CommentDO(comment);
        int add = commentDAO.add(commentDO);
        if (add < 1) {
            return 0;
        }
        return add;
    }

    @Override
    public int update(Comment comment) {
        if (comment == null) {
            return 0;
        }
        CommentDO commentDO = new CommentDO(comment);
        int update = commentDAO.update(commentDO);
        if (update < 1) {
            return 0;
        }
        return update;
    }

    @Override
    public int delete(long id) {
        int delete = commentDAO.delete(id);
        return delete;
    }

    @Override
    public List<Comment> findByRefId(String refId) {
        if (StringUtils.isEmpty(refId)) {
            return null;
        }
        List<Comment> comments = commentDAO.findByRefId(refId);
        if (CollectionUtils.isEmpty(comments)) {
            return null;
        }

        return comments;
    }

    @Override
    public int batchAdd(List<Comment> comments) {
        if (comments == null || CollectionUtils.isEmpty(comments)) {
            return 0;
        }
        List<CommentDO> commentDOS = comments.stream().map(comment -> {
            CommentDO commentDO = new CommentDO(comment);
            return commentDO;
        }).collect(Collectors.toList());
        int batchAdd = commentDAO.batchAdd(commentDOS);
        if (batchAdd < 1) {
            return 0;
        }
        return batchAdd;
    }

    @Override
    public List<Comment> findByUserIds(List<Long> ids) {
        if (ids == null || CollectionUtils.isEmpty(ids)){
            return null;
        }
        List<CommentDO> commentDOS = commentDAO.findByUserIds(ids);
        if (CollectionUtils.isEmpty(commentDOS)){
            return null;
        }
        List<User> users = userService.findByIds(ids);
        Map<Long,User> userMap = new HashMap<>();
        for (User user:users){
            userMap.put(user.getId(),user);
        }
        List<Comment> comments = new ArrayList<>();
        for (CommentDO commentDO :commentDOS){
            Comment comment = commentDO.toModel();
            User author = userMap.get(comment.getAuthor().getId());
            if (author != null){
                comment.setAuthor(author);
            }
            comments.add(comment);
        }
        return comments;
    }

    @Override
    public Result<Comment> post(String refId, long userId, long parentId, String content) {
        Result<Comment> result = new Result<>();

        if (StringUtils.isEmpty(refId) || StringUtils.isEmpty(content)) {
            result.setCode("500");
            result.setMessage("refId,userId,content不能为空");
            return result;
        }
        String body = StringEscapeUtils.escapeHtml4(content);
        CommentDO commentDO = new CommentDO();
        commentDO.setContent(body);
        commentDO.setParentId(parentId);
        commentDO.setRefId(refId);
        commentDO.setUserId(userId);
        commentDAO.add(commentDO);
        result.setSuccess(true);
        result.setData(commentDO.toModel());
        return result;
    }

    @Override
    public Result<List<Comment>> query(String refId) {
        Result<List<Comment>> result = new Result<>();
        //查询所有的评论记录包含回复的
        List<Comment> comments = commentDAO.findByRefId(refId);

        //构建 map 结构
        Map<Long, Comment> commentMap = new HashMap<>();
        //初始化一个虚拟根节点，0 可以对应的是所有一级评论的父亲
        commentMap.put(0L, new Comment());
        //把所有的评论转换为 map 数据
        comments.forEach(comment -> commentMap.put(comment.getId(), comment));
        // 再次遍历评论数据
        comments.forEach(comment -> {
            //得到父评论
            Comment parent = commentMap.get(comment.getParentId());
            if (parent != null) {
                // 初始化 children 变量
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                // 在父评论里添加回复数据
                parent.getChildren().add(comment);
            }
        });
// 得到所有的一级评论
        List<Comment> data = commentMap.get(0L).getChildren();
        result.setSuccess(true);
        result.setData(data);

        return result;
    }
}

